﻿using UnityEngine;
using UniFramework.Event;
using UniFramework.Module;
using YooAsset;
using System.Collections;
using System;
using UnityEngine.UI;
using Cysharp.Threading.Tasks.Triggers;

public class Boot : MonoBehaviour
{
	/// <summary>
	/// 资源系统运行模式
	/// </summary>
	public EPlayMode PlayMode = EPlayMode.EditorSimulateMode;

	void Awake()
	{
		Debug.Log($"资源系统运行模式：{PlayMode}");
		Application.targetFrameRate = 60;
		Application.runInBackground = true;

        DontDestroyOnLoad(this.gameObject);
	}
	void Start()
	{
        //// 初始化BetterStreaming
        //BetterStreamingAssets.Initialize();

        //// 初始化事件系统
        //UniEvent.Initalize();

        //// 初始化管理系统
        //UniModule.Initialize();

        //// 初始化资源系统
        //YooAssets.Initialize();

        //// 创建补丁管理器
        //UniModule.CreateModule<PatchManager>();

        //// 开始补丁更新流程
        //PatchManager.Instance.Run(PlayMode);

        StartCoroutine(TestLoad());
    }

    IEnumerator TestLoad()
    {
        yield return null;

        // 1.初始化资源系统
        YooAssets.Initialize();

        // 创建默认的资源包
        var package = YooAssets.CreateAssetsPackage("DefaultPackage");

        // 设置该资源包为默认的资源包，可以使用YooAssets相关加载接口加载该资源包内容。
        YooAssets.SetDefaultAssetsPackage(package);

        if (PlayMode == EPlayMode.EditorSimulateMode)
        {
            //编辑器模拟模式
            var initParameters = new EditorSimulateModeParameters();
            initParameters.SimulatePatchManifestPath = EditorSimulateModeHelper.SimulateBuild("DefaultPackage");
            yield return package.InitializeAsync(initParameters);
        }
        else if (PlayMode == EPlayMode.HostPlayMode)
        {
            //联机运行模式
            var initParameters = new HostPlayModeParameters();
            initParameters.QueryServices = new QueryStreamingAssetsFileServices();
            initParameters.DefaultHostServer = "http://127.0.0.1/CDN/PC/v1.0";
            initParameters.FallbackHostServer = "http://127.0.0.1/CDN/PC/v1.0";
            yield return package.InitializeAsync(initParameters);
        }
        else if (PlayMode == EPlayMode.OfflinePlayMode)
        {
            //单机模式
            var initParameters = new OfflinePlayModeParameters();
            yield return package.InitializeAsync(initParameters);

        }

        //2.获取资源版本
        var operation = package.UpdatePackageVersionAsync();
        yield return operation;

        if (operation.Status != EOperationStatus.Succeed)
        {
            //更新失败
            Debug.LogError(operation.Error);
            //TODO
            yield break;
        }
        string PackageVersion = operation.PackageVersion;

        //3.更新补丁清单
        var operation2 = package.UpdatePackageManifestAsync(PackageVersion);
        yield return operation2;

        if (operation2.Status != EOperationStatus.Succeed)
        {
            //更新失败
            Debug.LogError(operation2.Error);
            //TODO:
            yield break;
        }

        //4.下载补丁包
        yield return Download();
        //TODO:判断是否下载成功...

        
        //5.加载资源
        //加载场景
        //string location = "scene_home";
        //var sceneMode = UnityEngine.SceneManagement.LoadSceneMode.Single;
        //bool activateOnLoad = true;
        //SceneOperationHandle handle = package.LoadSceneAsync(location, sceneMode, activateOnLoad);
        //yield return handle;
        //Debug.Log($"Scene name is {handle.SceneObject.name}");

        //加载prefab
        //AssetOperationHandle handle2 = package.LoadAssetAsync<GameObject>("UICanvas");
        //yield return handle2;
        //GameObject uiCanvas = handle2.InstantiateSync();
        //Debug.Log($"Prefab name is {uiCanvas.name}");

        //AssetOperationHandle handle3 = package.LoadAssetAsync<GameObject>("UIHome");
        //yield return handle3;
        //GameObject uiHome = handle3.InstantiateSync();
        //Debug.Log($"Prefab name is {uiHome.name}");
        //uiHome.transform.parent = uiCanvas.transform;
        //uiHome.GetComponent<RectTransform>().offsetMax = new Vector2(0, 0);

        ////加载原生文件
        //RawFileOperationHandle handle4 = package.LoadRawFileAsync("RawFile");
        //yield return handle4;
        //// byte[] fileData = handle.GetRawFileData();
        //string fileText = handle4.GetRawFileText();
        //Debug.Log("原生文件： " + fileText);

        ////访问图集的精灵对象
        //SubAssetsOperationHandle handle5 = package.LoadSubAssetsAsync<Sprite>("sprites");
        //yield return handle5;
        //var sprite = handle5.GetSubAssetObject<Sprite>("sprites_30");
        //Debug.Log($"Sprite name is {sprite.name}");
        //uiHome.transform.Find("Image").GetComponent<Image>().sprite = sprite;

        ////通过资源标签来获取资源信息列表。
        //AssetInfo[] assetInfos = package.GetAssetInfos("Effect");
        //foreach (var assetInfo in assetInfos)
        //{
        //    Debug.Log(assetInfo.AssetPath);
        //}

        //委托加载
        //AssetOperationHandle handle6 = package.LoadAssetAsync<GameObject>("player_ship");
        //handle6.Completed += Handle_Completed;

        //Tash加载
        //TestTask();

        //AssetOperationHandle handle2 = package.LoadAssetAsync<GameObject>("player_ship");
        //yield return handle2;
        //GameObject go = handle2.InstantiateSync();

        //yield return new WaitForSeconds(3);

        ////Destroy(go);
        //handle2.Release();
    }

    // Task加载方式
    async void TestTask()
    {
        var package = YooAssets.GetAssetsPackage("DefaultPackage");
        AssetOperationHandle handle = package.LoadAssetAsync<GameObject>("player_ship");
        await handle.Task;
        GameObject go = handle.InstantiateSync();

    } 

    void Handle_Completed(AssetOperationHandle handle)
    {
        GameObject go = handle.InstantiateSync();
    }

    IEnumerator Download()
    {
        int downloadingMaxNum = 10;
        int failedTryAgain = 3;
        int timeout = 60;
        var package = YooAssets.GetAssetsPackage("DefaultPackage");
        var downloader = package.CreatePatchDownloader(downloadingMaxNum, failedTryAgain, timeout);

        //没有需要下载的资源
        if (downloader.TotalDownloadCount == 0)
        {
            yield break;
        }

        //需要下载的文件总数和总大小
        int totalDownloadCount = downloader.TotalDownloadCount;
        long totalDownloadBytes = downloader.TotalDownloadBytes;

        //注册回调方法
        downloader.OnDownloadErrorCallback = OnDownloadErrorFunction;
        downloader.OnDownloadProgressCallback = OnDownloadProgressUpdateFunction;
        downloader.OnDownloadOverCallback = OnDownloadOverFunction;
        downloader.OnStartDownloadFileCallback = OnStartDownloadFileFunction;

        //开启下载
        downloader.BeginDownload();
        yield return downloader;

        //检测下载结果
        if (downloader.Status == EOperationStatus.Succeed)
        {
            //下载成功
            Debug.Log("更新完成!");
            //TODO:
        }
        else
        {
            //下载失败
            Debug.LogError("更新失败！");
            //TODO:
        }
    }

    /// <summary>
    /// 开始下载
    /// </summary>
    /// <param name="fileName"></param>
    /// <param name="sizeBytes"></param>
    /// <exception cref="NotImplementedException"></exception>
    private void OnStartDownloadFileFunction(string fileName, long sizeBytes)
    {
        Debug.Log(string.Format("开始下载：文件名：{0}, 文件大小：{1}", fileName, sizeBytes));
    }

    /// <summary>
    /// 下载完成
    /// </summary>
    /// <param name="isSucceed"></param>
    /// <exception cref="NotImplementedException"></exception>
    private void OnDownloadOverFunction(bool isSucceed)
    {
        Debug.Log("下载" + (isSucceed ? "成功" : "失败"));
    }

    /// <summary>
    /// 更新中
    /// </summary>
    /// <param name="totalDownloadCount"></param>
    /// <param name="currentDownloadCount"></param>
    /// <param name="totalDownloadBytes"></param>
    /// <param name="currentDownloadBytes"></param>
    /// <exception cref="NotImplementedException"></exception>
    private void OnDownloadProgressUpdateFunction(int totalDownloadCount, int currentDownloadCount, long totalDownloadBytes, long currentDownloadBytes)
    {
        Debug.Log(string.Format("文件总数：{0}, 已下载文件数：{1}, 下载总大小：{2}, 已下载大小：{3}", totalDownloadCount, currentDownloadCount, totalDownloadBytes, currentDownloadBytes));
    }

    /// <summary>
    /// 下载出错
    /// </summary>
    /// <param name="fileName"></param>
    /// <param name="error"></param>
    /// <exception cref="NotImplementedException"></exception>
    private void OnDownloadErrorFunction(string fileName, string error)
    {
        Debug.LogError(string.Format("下载出错：文件名：{0}, 错误信息：{1}", fileName, error));
    }

    // 内置文件查询服务类
    private class QueryStreamingAssetsFileServices : IQueryServices
    {
        public bool QueryStreamingAssets(string fileName)
        {
            // 注意：使用了BetterStreamingAssets插件，使用前需要初始化该插件！
            string buildinFolderName = YooAssets.GetStreamingAssetBuildinFolderName();
            return BetterStreamingAssets.FileExists($"{buildinFolderName}/{fileName}");
        }
    }
}